<template>
  <div class="search">
    <el-row class="operation">
      <el-button @click="add(formAddRef)" type="primary" :icon="Plus">添加子菜单</el-button>
      <el-button :icon="Plus" @click="addRoot(formAddRef)">添加顶级菜单</el-button>
      <el-button :disabled="menuView.selectList.length === 0" style="margin-right: 13px" :icon="DeleteFilled" @click="deleteAll">批量删除</el-button>
      <el-button :icon="Refresh" @click="getList">刷新菜单</el-button>
    </el-row>
    <el-row style="margin-top:10px;">
      <el-col :md="15" :lg="13" :xl="12" :xxl="9">
        <el-alert :closable="false">
          <template #title>
            当前选择编辑：
            <span class="select-title">{{ menuView.editTitle }}</span>
            <span class="select-clear" v-if="formInfo.id" @click="cancelEdit(formRef)"> 取消选择 </span>
          </template>
        </el-alert>
        <el-input
          style="margin-top:10px;"
          v-model="filterText"
          suffix="ios-search"
          placeholder="输入菜单名搜索"
          clearable
        />
        <div class="tree-bar" :style="{maxHeight: menuView.maxHeight}">
          <el-tree
            ref="treeRef"
            show-checkbox
            :data="menuView.data"
            node-key="id"
            :expand-on-click-node="false"
            highlight-current
            :filter-node-method="filterNode"
            :props="{label: 'title'}"
            @node-click="selectTree"
            @check-change="changeCheck"
          />
        </div>
      </el-col>
      <el-col :md="15" :lg="13" :xl="12" :xxl="9">
        <el-form ref="formRef" :model="formInfo" :label-width="100" :rules="formValidate">
          <el-form-item label="菜单名称" prop="title">
            <el-input v-model="formInfo.title" />
          </el-form-item>
          <el-form-item label="菜单鉴权" prop="permission">
            <el-checkbox :true-label="1" :false-label="0" border v-model="formInfo.auth"> 需要登录</el-checkbox>
            <el-checkbox :true-label="1" :false-label="0" border v-model="formInfo.permission"> 访问鉴权</el-checkbox>
            <el-checkbox :true-label="1" :false-label="0" border v-model="formInfo.log"> 记录日志</el-checkbox>
            <el-checkbox :true-label="1" :false-label="0" border v-model="formInfo.show"> 显示与否</el-checkbox>
          </el-form-item>
          <el-form-item label="菜单类型" prop="level">
            <el-radio-group v-model="formInfo.level">
              <el-radio :label="1" border disabled>顶级菜单</el-radio>
              <el-radio :label="2" border disabled>二级菜单</el-radio>
              <el-radio :label="3" border disabled>页内按钮</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="请求方式" prop="method">
            <el-radio-group v-model="formInfo.method">
              <el-radio :label="1" border> GET</el-radio>
              <el-radio :label="2" border> POST</el-radio>
              <el-radio :label="3" border> PUT</el-radio>
              <el-radio :label="4" border> DELETE</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="菜单图标" prop="icon">
            <select-icon v-model:iconValue="formInfo.icon" />
          </el-form-item>
          <el-form-item label="后端类库" prop="url">
            <el-input v-model="formInfo.url">
              <template #prepend>admin/</template>
            </el-input>
          </el-form-item>
          <el-form-item label="前端路由" prop="router">
            <el-input v-model="formInfo.router" />
          </el-form-item>
          <el-form-item label="前端组件" prop="component">
            <el-input v-model="formInfo.component" />
          </el-form-item>
          <el-form-item label="菜单排序" prop="sort">
            <el-tooltip trigger="hover" placement="right" content="值越小越靠前，支持小数">
              <el-input-number :max="1000" :min="0" v-model="formInfo.sort" />
            </el-tooltip>
          </el-form-item>
          <el-form-item>
            <el-button
              :loading="menuView.submitLoading"
              type="primary"
              :icon="Edit"
              class="margin-right-5"
              @click="submitEdit(formRef)"
            >修改并保存
            </el-button>
            <el-button @click="cancelEdit(formRef)">重置</el-button>
          </el-form-item>
        </el-form>
      </el-col>
    </el-row>
    <el-dialog :title="menuView.modalTitle" v-model="menuView.modalVisible" :width="800">
      <el-form ref="formAddRef" :model="formAdd" :label-width="100" :rules="formValidate">
        <div v-if="menuView.showParent">
          <el-form-item label="上级菜单">
            <el-tag effect="dark">{{ formInfo.title }}</el-tag>
          </el-form-item>
        </div>
        <el-form-item label="菜单名称" prop="title">
          <el-input v-model="formAdd.title" />
        </el-form-item>
        <el-form-item label="菜单鉴权" prop="permission">
          <el-checkbox :true-label="1" :false-label="0" border v-model="formAdd.auth"> 需要登录 </el-checkbox>
          <el-checkbox :true-label="1" :false-label="0" border v-model="formAdd.permission"> 访问鉴权 </el-checkbox>
          <el-checkbox :true-label="1" :false-label="0" border v-model="formAdd.log"> 记录日志 </el-checkbox>
          <el-checkbox :true-label="1" :false-label="0" border v-model="formAdd.show"> 显示与否 </el-checkbox>
        </el-form-item>
        <el-form-item label="菜单类型" prop="level">
          <el-radio-group v-model="formAdd.level">
            <el-radio :label="1" border disabled>顶级菜单</el-radio>
            <el-radio :label="2" border disabled>二级菜单</el-radio>
            <el-radio :label="3" border disabled>页内按钮</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="请求方式" prop="method">
          <el-radio-group v-model="formAdd.method">
            <el-radio :label="1" border> GET </el-radio>
            <el-radio :label="2" border> POST </el-radio>
            <el-radio :label="3" border> PUT </el-radio>
            <el-radio :label="4" border> DELETE </el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="菜单图标" prop="icon">
          <select-icon v-model:iconValue="formAdd.icon" />
        </el-form-item>
        <el-form-item label="后端类库" prop="url">
          <el-input v-model="formAdd.url">
            <template #prepend>admin/</template>
          </el-input>
        </el-form-item>
        <el-form-item label="前端路由" prop="router">
          <el-input v-model="formAdd.router" />
        </el-form-item>
        <el-form-item label="前端组件" prop="component">
          <el-input v-model="formAdd.component" />
        </el-form-item>
        <el-form-item label="菜单排序" prop="sort">
          <el-tooltip trigger="hover" placement="right" content="值越小越靠前，支持小数">
            <el-input-number :max="1000" :min="0" v-model="formAdd.sort" />
          </el-tooltip>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button link @click="menuView.modalVisible=false">取消</el-button>
        <el-button type="primary" :loading="menuView.submitLoading" @click="submitAdd(formAddRef)">提交</el-button>
      </template>
    </el-dialog>
  </div>
</template>
<script lang="ts" setup>
import {ref, reactive, onMounted, watch} from 'vue';
import {Refresh, Plus, DeleteFilled, Edit} from '@element-plus/icons-vue';
import type {ElForm} from "element-plus";
import {ElMessage, ElTree} from 'element-plus';
import {MenuAddForm, MenuForm} from "@/api/interface/menu";
import SelectIcon from "@/components/SelectIcon/index.vue";
import {getMenuList, editMenu, deleteMenu, addMenu} from "@/api/modules/menu";
import {TreeKey} from "element-plus/es/components/tree/src/tree.type";

interface MenuView {
	loading: boolean, // 树加载状态
	maxHeight: string,
	modalVisible: boolean, // 添加显示
	selectList: Array<TreeKey>, // 多选数据
	showParent: boolean, // 显示上级标识
	modalTitle: string, // 添加标题
	editTitle: string, // 编辑节点名称
	searchKey: string, // 搜索树
	submitLoading: boolean,
	data: []
}
type FormInstance = InstanceType<typeof ElForm>
const formRef = ref<FormInstance>()
const formAddRef = ref<FormInstance>()
const filterText = ref('')
const treeRef = ref<InstanceType<typeof ElTree>>()

const menuView = reactive<MenuView>({
	loading: false, // 树加载状态
	maxHeight: '',
	modalVisible: false, // 添加显示
	selectList: [], // 多选数据
	showParent: false, // 显示上级标识
	modalTitle: '', // 添加标题
	editTitle: '', // 编辑节点名称
	searchKey: '', // 搜索树
	submitLoading: false,
	data: []
});
const formAdd = reactive<MenuAddForm>({
	fid: 0,
	title: '',
	level: 0,
	icon: '',
	router: '',
	method: 1,
	url: '',
	component: '',
	auth: 1,
	log: 1,
	permission: 1,
	show: 1,
	sort: 0
});
const formInfo = reactive<MenuForm>({
	id: 0,
	title: '',
	level: 0,
	icon: '',
	router: '',
	method: 1,
	url: '',
	component: '',
	auth: 1,
	log: 1,
	permission: 1,
	show: 1,
	sort: 0
});
const formValidate = reactive({
	title: [
		{required: true, message: '名称不能为空', trigger: 'blur'}
	],
	sort: [
		{required: true, type: 'number', message: '排序值不能为空', trigger: 'blur'}
	]
});
onMounted(() => {
	let height = document.documentElement.clientHeight
	menuView.maxHeight = Number(height - 330) + 'px'
	getList()
});
watch(filterText, (val) => {
	treeRef.value!.filter(val)
})

const getList = async () => {
	menuView.loading = true
	const res = await getMenuList(menuView.searchKey)
	menuView.data = res.data?.list
	menuView.loading = false
	menuView.selectList = []
}

const filterNode = (value: string, data: MenuForm) => {
	if (!value) return true
	return data.title.includes(value)
}
const selectTree = (b: any) => {
	Object.assign(formInfo, b)
  if (formInfo.url) {
		formInfo.url = formInfo.url.replace('admin/', '')
	}
	menuView.editTitle = b.title
}
const submitEdit = (formEl: FormInstance | undefined) => {
	if (!formEl) return;
	menuView.submitLoading = true
	formEl.validate(async valid => {
		if (valid) {
			if (!formInfo.id) {
				ElMessage.warning('请先点击选择要修改的节点')
				return
			}
			delete formInfo.children
			await editMenu(formInfo);
			ElMessage.success("操作成功！");
			menuView.submitLoading = false
			getList()
		}
	})
}
const cancelEdit = (formEl: FormInstance | undefined) => {
	formEl?.resetFields()
	formInfo.id = 0
	menuView.editTitle = ''
}
const changeCheck = () => {
	menuView.selectList = treeRef.value!.getCheckedKeys(false)
}
const deleteAll = async () => {
	if (menuView.selectList.length > 0) {
		await deleteMenu(menuView.selectList);
		await getList()
	}
}

const submitAdd = (formEl: FormInstance | undefined) => {
	if (!formEl) return;
	formEl.validate(async valid => {
		if (valid) {
			menuView.submitLoading = true
			const res = await addMenu(formAdd)
			await getList()
			ElMessage.success(res.msg)
			menuView.submitLoading = false
			menuView.modalVisible = false
		}
	})
}
const add = (formEl: FormInstance | undefined) => {
	if (!formInfo.id) {
		ElMessage.warning('请先点击选择一个菜单')
		return
	}
	menuView.modalTitle = '添加子菜单'
	menuView.showParent = true
	formEl?.resetFields()
	formAdd.fid = formInfo.id
	formAdd.level = formInfo.level + 1
	menuView.modalVisible = true
};
const addRoot = (formEl: FormInstance | undefined) => {
	formEl?.resetFields()
	formAdd.fid = 0
	menuView.modalTitle = '添加顶级菜单'
	formAdd.level = 1
	menuView.showParent = false
	menuView.modalVisible = true
}

</script>

<style scoped lang="scss">
@import "./menu";
</style>
